package cs2114.alarmclock;

import java.util.Calendar;
import android.text.format.Time;
import android.graphics.drawable.*;
import android.graphics.BitmapFactory;
import android.graphics.Bitmap;
import android.view.MotionEvent;
import android.graphics.Canvas;
import java.util.Observable;
import java.util.Observer;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;

// -------------------------------------------------------------------------
/**
 * A view that renders the data in the Maze model as a rectangles on the
 * screen, and provides the interaction that allows the user to manipulate
 * the maze.
 *
 * @author  William Lucy
 * @version 2011.11.02
 */
public class MainView extends View
{
    //~ Static/instance variables .............................................
    //private PhotoModel model;         // The model is declared
    private Bitmap clockFace;
    private Bitmap one;
    private Bitmap two;
    private Bitmap three;
    private Bitmap four;
    private Bitmap five;
    private Bitmap six;
    private Bitmap seven;
    private Bitmap eight;
    private Bitmap nine;
    private Bitmap zero;
    private Bitmap colon;
    private Bitmap backgrounds;
    private boolean background;


    //~ Constructor ...........................................................

    // ----------------------------------------------------------
    /**
     * Creates a new RubberLinesView.
     *
     * A constructor with these arguments is required for any view that will be
     * added to a layout XML file. Just pass the arguments along to the
     * superclass constructor, and then perform any other initialization after
     * that if you need to.
     *
     * @param context the Context that the view is running in
     * @param attrs the attributes of the XML tag that is inflating the view
     */
    public MainView(Context context, AttributeSet attrs)
    {
        super(context, attrs);
        background = false;     // initializes background boolean
        initializeBitmaps(context);

        // Adds a photo to the background; a method to change this will
        // be implemented after some kind of photo selection is implemented.
        // TODO: implement background changing (requires photo model)
    }


    //~ Methods ...............................................................

    // ----------------------------------------------------------
    /**
     * Sets the model that will be rendered by this view. Calling this method
     * also adds the view as an observer for the model.
     *
     * @param model the model

    public void setModel(PhotoModel model)
    {
        this.model = model;
        model.addObserver(new MazeObserver());
    }*/


    // ----------------------------------------------------------
    /**
     * Called when a touch event occurs on the view; either pressing the finger
     * down for the first time, moving it on the screen, or lifting it back up.
     *
     * @param e a MotionEvent object that describes the touch event
     * @return true if this method handled the touch, or false if it did not
     */
    @Override
    public boolean onTouchEvent(MotionEvent e)
    {
        // Handles the ACTION_DOWN event
        if (e.getAction() == MotionEvent.ACTION_DOWN)
        {
            // Handles touch down event
            // touching down will probably move to the next image
            // TODO: implement ACTION_DOWN given a photo model
            return true;
        }

        // Handles the ACTION_MOVE event
        else if (e.getAction() == MotionEvent.ACTION_MOVE)
        {
            // Handles moving touch
            // if drag right, go to previous picture;
            // if drag left, go to next picture
            // TODO: implement ACTION_MOVE given a photo model
            return true;
        }

        else
        {
            // For any other touch event, ignore it.
            return false;
        }
    }


    // ----------------------------------------------------------
    /**
     * Called when the view is asked to redraw its conents.
     *
     * @param canvas an object that represents the canvas to be drawn on
     */
    @Override
    public void onDraw(Canvas canvas)
    {
        // Bail out early if the model is null and there's nothing for us to
        // draw. When we edit the XML layout for the view, the views are
        // actually drawn live and this method gets called, but in the GUI
        // designer there won't actually be a model set! So this is a safety
        // check to make sure that we don't break that.

        // TODO: implement an image-selection model.
        /**
        if (model == null)
        {
            return;
        }
         */

        // Draws the background, and then draws the clock.
        drawBackground(canvas);
        drawClock(canvas);
    }


    /**
     * Draws the clock face; updates the clock's time using the system time.
     * This particular clock utilizes predrawn resource images for each digit.
     * @param canvas is the current Canvas
     */
    public void drawClock(Canvas canvas)
    {
        // draws the middle colon
        canvas.drawBitmap(colon, (getWidth()/2)-10, 68f, null);

        Bitmap bit;
        int time = 0;

        // Gets the current minute and hour from Calendar
        Calendar c = Calendar.getInstance();
        int minute = c.get(Calendar.MINUTE);
        int hour = c.get(Calendar.HOUR);

        // Loops through each digit (out of four)
        for (int i = 0; i < 4; i++)
        {
            switch (i)
            {
                // The value of each digit is determined
                case 0: time = minute%10; break;
                case 1: time = minute/10; break;
                case 2: time = hour/10; break;
                case 3: time = hour%10; break;
            }

            switch (time) {
                // The current digit is chosen from the available bitmaps
                case 0:  bit = zero;    break;
                case 1:  bit = one;     break;
                case 2:  bit = two;     break;
                case 3:  bit = three;   break;
                case 4:  bit = four;    break;
                case 5:  bit = five;    break;
                case 6:  bit = six;     break;
                case 7:  bit = seven;   break;
                case 8:  bit = eight;   break;
                case 9:  bit = nine;    break;
                default: bit = nine;    break;
            }

            switch (i)
            {
                // The proper digit is set
                case 0: canvas.drawBitmap(bit,
                    (getWidth()/2)+157, 17f, null); break;
                case 1: canvas.drawBitmap(bit,
                    (getWidth()/2)+25, 17f, null); break;
                case 2: canvas.drawBitmap(bit,
                    (getWidth()/2)-280, 17f, null); break;
                case 3: canvas.drawBitmap(bit,
                    (getWidth()/2)-147, 17f, null); break;
            }
        }
        postInvalidate();
    }


    /**
     * Draws the view's background; uses a default bitmap, or a user-selected
     * image.
     * @param canvas is the current canvas
     */
    private void drawBackground(Canvas canvas)
    {
        // This just sets the background to an image in /res/drawable.
        // TODO: implement user selection of backgrounds
        canvas.drawBitmap(backgrounds, 0f, 0f, null);

        /**
        if (background)
        {
            canvas.drawBitmap(clockFace, 0f, 0f, backgroundPaint);
        }
        setBackgroundResource(R.drawable.background);
         */
    }


     /**
      * Initializes the various bitmaps that will be used for the clock
      */
     private void initializeBitmaps(Context context)
     {
         Drawable backgroundd = context.getResources().getDrawable(
             R.drawable.background);
         backgrounds = ((BitmapDrawable)backgroundd).getBitmap();

         Drawable clocks = context.getResources().getDrawable(
             R.drawable.clock);
         clockFace = ((BitmapDrawable)clocks).getBitmap();

         Drawable zerod = context.getResources().getDrawable(
             R.drawable.zero);
         zero = ((BitmapDrawable)zerod).getBitmap();

         Drawable oned = context.getResources().getDrawable(
             R.drawable.one);
         one = ((BitmapDrawable)oned).getBitmap();

         Drawable twod = context.getResources().getDrawable(
             R.drawable.two);
         two = ((BitmapDrawable)twod).getBitmap();

         Drawable threed = context.getResources().getDrawable(
             R.drawable.three);
         three = ((BitmapDrawable)threed).getBitmap();

         Drawable fourd = context.getResources().getDrawable(
             R.drawable.four);
         four = ((BitmapDrawable)fourd).getBitmap();

         Drawable fived = context.getResources().getDrawable(
             R.drawable.five);
         five = ((BitmapDrawable)fived).getBitmap();

         Drawable sixd = context.getResources().getDrawable(
             R.drawable.six);
         six = ((BitmapDrawable)sixd).getBitmap();

         Drawable sevend = context.getResources().getDrawable(
             R.drawable.seven);
         seven = ((BitmapDrawable)sevend).getBitmap();

         Drawable eightd = context.getResources().getDrawable(
             R.drawable.eight);
         eight = ((BitmapDrawable)eightd).getBitmap();

         Drawable nind = context.getResources().getDrawable(
             R.drawable.nine);
         nine = ((BitmapDrawable)nind).getBitmap();

         Drawable colond = context.getResources().getDrawable(
             R.drawable.colon);
         colon = ((BitmapDrawable)colond).getBitmap();
     }



    // ----------------------------------------------------------
    /**
     * An observer that listens for changes made to the Maze class.
     * This is a nested class inside the view so that it can still access
     * methods that belong to the surrounding view.
     */
    private class MazeObserver implements Observer
    {
        //~ Methods ...........................................................

        // ----------------------------------------------------------
        /**
         * Called when Maze is changed (for example, when the
         * user drags a finger around the view).
         *
         * @param observable the Observable object that was changed
         * @param data extra data about the notification; unused here
         */
        public void update(Observable observable, Object data)
        {
            // The invalidate() method is used to force a view to be repainted
            // at the earliest opportunity (which in most cases is essentially
            // immediately, but may not always be). Note that this is a method
            // on the View class, not the Observer.

            invalidate();
        }
    }
}

